package tech.aistar.corejava.day10;

/**
 * @Author:         lya
 * @Description:   本类的作用描述:封箱拆箱
 * @param
 * @return:
 * @CreateDate:    2019/7/27 8:57
 * @Version:       1.0
*/
public class IntegerValueOfDemo {
    public static void main(String[] args) {
        /**
         * Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

         　　　　　Double、Float的valueOf方法的实现是类似的。
         */

        /**Integer valueOf()源码
         public static Integer valueOf(int i) {
         if (i >= IntegerCache.low && i <= IntegerCache.high)
         return IntegerCache.cache[i + (-IntegerCache.low)];
         return new Integer(i);
         }
         */

        /**IntegerCache源码
         private static class IntegerCache {
         static final int low = -128;
         static final int high;
         static final Integer cache[];

         static {
         // high value may be configured by property
         int h = 127;
         String integerCacheHighPropValue =
         sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
         if (integerCacheHighPropValue != null) {
         try {
         int i = parseInt(integerCacheHighPropValue);
         i = Math.max(i, 127);
         // Maximum array size is Integer.MAX_VALUE
         h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
         } catch( NumberFormatException nfe) {
         // If the property cannot be parsed into an int, ignore it.
         }
         }
         high = h;

         cache = new Integer[(high - low) + 1];
         int j = low;
         for(int k = 0; k < cache.length; k++)
         cache[k] = new Integer(j++);

         // range [-128, 127] must be interned (JLS7 5.1.7)
         assert IntegerCache.high >= 127;
         }

         private IntegerCache() {}
         }
         */

        System.out.println("==========Integer类型封箱测试===========");
        //[-128,127]区间,都是直接将数字放到Integer[] caches,缓冲区
        //不在这个区间的,直接new
        Integer i = Integer.valueOf(127);
        Integer j = Integer.valueOf(127);
        System.out.println(i == j);//true

        Integer a1 = Integer.valueOf(128);
        Integer b1 = Integer.valueOf(128);
        System.out.println(a1 == b1);//false


        /**
         * Double.valueOf()源码
         *  public static Double valueOf(double d) {
         *  return new Double(d);
         *  }
         */
        System.out.println("==========Double类型封箱测试===========");
        Double i1 = Double.valueOf(100);
        Double i2 = Double.valueOf(100);
        Double i3 = Double.valueOf(200);
        Double i4 = Double.valueOf(200);

        System.out.println(i1 == i2);//false
        System.out.println(i3 == i4);//false

        /**
         public static Boolean valueOf(boolean b) {
         return (b ? TRUE : FALSE);
         }

         public static final Boolean TRUE = new Boolean(true);

         public static final Boolean FALSE = new Boolean(false);

         而其中的 TRUE 和 FALSE 是 Boolean中定义的2个静态成员属性：
         */

        System.out.println("==========Boolean类型封箱测试===========");
        Boolean j1 = false;
        Boolean j2 = false;
        Boolean j3 = true;
        Boolean j4 = true;

        System.out.println(j1==j2);//true
        System.out.println(j3==j4);//true

        System.out.println("=========比较测试==========");
        Integer a = 100;
        Integer b = 200;
        Integer c = 300;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 300L;
        Long h = 200L;
        System.out.println(e == f);//false, "=="运算符比较指向的是否是同一个对象
        System.out.println(c == (a+b));//true,  "=="运算符当其中有一个操作数是表达式（即包含算术运算）则比较的是数值
        System.out.println(c.equals(a+b));//true, equals方法并不会进行类型转换数值类型都相同
        System.out.println(g.equals(a+b));//false,  g的类型还是Long,(a+b)的类型还是Integer
        System.out.println(g ==(a+b));//true,  数值相同
        System.out.println(g.equals(a+h));//true,   数值相同

        /**
         当 "=="运算符的两个操作数都是 包装器类型的引用，则是比较指向的是否是同一个对象，
         而如果其中有一个操作数是表达式（即包含算术运算）则比较的是数值（即会触发自动拆箱的过程）。
         另外，对于包装器类型，equals方法并不会进行类型转换。
         */
    }
}
